# import datetime
# from django.shortcuts import render
# from alipay import AliPay,DCAliPay,ISVAliPay
# from alipay.utils import AliPayConfig
#
# from rest_framework.views import APIView
# from django.conf import settings
# from rest_framework.response import Response
# from course.models import CourseExpire,Course
# from order.models import Order
# from coupon.models import UserCoupon
# from users.models import User,Credit,UserCourse
# from rest_framework.permissions import IsAuthenticated
# from django_redis import get_redis_connection
# from django.db import transaction
#
# class PaymentView(APIView):
#
#     permission_classes = [IsAuthenticated,]
#     def get(self,request):
#         order_number = request.query_params.get('order_number')
#         try:
#             order_obj = Order.objects.get(order_number=order_number)
#         except:
#             return Response({'error':'订单号有误!'},status=400)
#
#         alipay = AliPay(
#             appid=settings.ALIPAY_SETTING.get('APP_ID'),
#             app_notify_url=None,  # 默认回调url
#             app_private_key_string=open(settings.ALIPAY_SETTING.get('APP_PRIVATE_KEY_STRING')).read(),
#             # 支付宝的公钥，验证支付宝回传消息使用，不是你自己的公钥,
#             alipay_public_key_string=open(settings.ALIPAY_SETTING.get('ALIPAY_PUBLIC_KEY_STRING')).read(),
#             sign_type=settings.ALIPAY_SETTING.get('SIGN_TYPE'),  # RSA 或者 RSA2
#             debug = settings.ALIPAY_SETTING.get('DEBUG'),  # 默认False
#             # config = AliPayConfig(timeout=15)  # 可选, 请求超时时间
#         )
#         order_string = alipay.api_alipay_trade_page_pay(
#             out_trade_no=order_number,
#             total_amount=float(order_obj.real_price),
#             subject=order_obj.order_title,
#             return_url=settings.ALIPAY_SETTING.get('RETURN_URL'),
#             notify_url=settings.ALIPAY_SETTING.get('NOTIFY_URL') # 可选, 不填则使用默认notify url
#         )
#         pay_page_url = settings.ALIPAY_SETTING.get('GATEWAY') + '?' + order_string
#
#         return Response({'url':pay_page_url})
#
# class PaymentCheckView(APIView):
#     permission_classes = [IsAuthenticated,]
#     def get(self,request):
#         data = request.query_params.dict()
#         signature = data.pop('sign')
#         alipay = AliPay(
#             appid=settings.ALIPAY_SETTING.get('APP_ID'),
#             app_notify_url=None,  # 默认回调url
#             app_private_key_string=open(settings.ALIPAY_SETTING.get('APP_PRIVATE_KEY_STRING')).read(),
#             # 支付宝的公钥，验证支付宝回传消息使用，不是你自己的公钥,
#             alipay_public_key_string=open(settings.ALIPAY_SETTING.get('ALIPAY_PUBLIC_KEY_STRING')).read(),
#             sign_type=settings.ALIPAY_SETTING.get('SIGN_TYPE'),  # RSA 或者 RSA2
#             debug=settings.ALIPAY_SETTING.get('DEBUG'),  # 默认False
#             # config = AliPayConfig(timeout=15)  # 可选, 请求超时时间
#         )
#
#         # verification
#         success = alipay.verify(data,signature)
#         if success:
#             res_data = self.res_data_return(request,data)
#         else:
#             return Response({'error':'支付宝响应数据校验失败'},status=400)
#
#     # 支付宝异步结果通知处理
#     def post(self,request):
#         data = request.query_params.dict()
#         signature = data.pop('sign')
#         alipay = AliPay(
#             appid=settings.ALIPAY_SETTING.get('APP_ID'),
#             app_notify_url=None,  # 默认回调url
#             app_private_key_string=open(settings.ALIPAY_SETTING.get('APP_PRIVATE_KEY_STRING')).read(),
#             # 支付宝的公钥，验证支付宝回传消息使用，不是你自己的公钥,
#             alipay_public_key_string=open(settings.ALIPAY_SETTING.get('ALIPAY_PUBLIC_KEY_STRING')).read(),
#             sign_type=settings.ALIPAY_SETTING.get('SIGN_TYPE'),  # RSA 或者 RSA2
#             debug=settings.ALIPAY_SETTING.get('DEBUG'),  # 默认False
#             # config = AliPayConfig(timeout=15)  # 可选, 请求超时时间
#         )
#
#         # verification
#         success = alipay.verify(data,signature)
#         if success and data['trade_status'] in ("TRADE_SUCCESS","TRADE_FINISHED"):
#             self.res_data_return(request,data)
#         else:
#             return Response({'error':'支付宝相应数据校验失败'},status=400)
#
#     def res_data_return(self,request,data):
#         current_time = datetime.datetime.now()
#         order_number = data.get('out_trade_no')
#         trade_no = data.get('trade_no')
#         total_amount = data.get('total_amount')
#
#         res_data = {
#             'total_price': total_amount,
#             'pay_time': current_time,
#             'course_name': [],
#         }
#         # 响应信息
#         with transaction.atomic():
#             order_obj = Order.objects.get(order_number=order_number)
#             order_obj.order_status = 1
#             order_obj.save()
#
#             # 2 优惠券修改状态为已经使用
#             coupon_obj = UserCoupon.objects.get(id=order_obj.coupon)
#             coupon_obj.is_use = True
#             coupon_obj.save()
#
#             # 3 积分修改,积分记录添加
#             user_obj = User.objects.get(id=request.user.id)
#             user_obj.credit -= order_obj.credit
#             user_obj.save()
#             Credit.objects.create(user=user_obj,opera=2,numbner=order_obj.credit)
#             # 5 购物车删除对应课程
#             conn = get_redis_connection('cart')
#             selected_course = conn.smembers(f'selected_{request.user.id}') # 所有选中课程
#             for course_id_bytes in selected_course:
#                 course_id = course_id_bytes.decode()
#                 expire_id = int(conn.hget(request.user.id,course_id).decode())
#
#                 course_obj = Course.objects.get(id=course_id)
#                 res_data['course_name'].append(course_obj.name)
#
#                 if expire_id > 0:
#                     expire = CourseExpire.objects.get(id=expire_id).expire_time
#                 else:
#                     expire = 100000
#                 conn.hdel(request.user.id,course_id)
#                 conn.srem(f'selected_{request.user.id}',course_id)
#
#                 # 4 保存支付宝的交易帐号流水号(购买记录表)
#                 out_time = current_time + datetime.timedelta(days=expire)
#
#                 UserCourse.objects.create(
#                     user_id = request.user.id,
#                     course_id = course_id,
#                     trade_no = trade_no,
#                     buy_type = 1,
#                     pay_time = current_time,
#                     out_time = out_time,
#                 )
#         return res_data


from django.shortcuts import render
import datetime
from alipay import AliPay, DCAliPay, ISVAliPay
from alipay.utils import AliPayConfig
# Create your views here.
from rest_framework.views import APIView
from django.conf import settings
from rest_framework.response import  Response
from course.models import CourseExpire,Course
from order.models import Order
from coupon.models import UserCoupon
from users.models import User, Credit, UserCourse
from rest_framework.permissions import IsAuthenticated
from django_redis import get_redis_connection
from django.db import transaction


class PaymentView(APIView):
    permission_classes = [IsAuthenticated, ]

    # 获取支付页面的url用的
    def get(self,request):
        order_number = request.query_params.get('order_number')
        try:
            order_obj = Order.objects.get(order_number=order_number)
        except:
            return Response({'error':'订单号有误'},status=400)

        alipay = AliPay(
            appid=settings.ALIPAY_SETTING.get('APP_ID'),
            app_notify_url=None,  # 默认回调url
            app_private_key_string=open(settings.ALIPAY_SETTING.get('APP_PRIVATE_KEY_STRING')).read(),
            # 支付宝的公钥，验证支付宝回传消息使用，不是你自己的公钥,
            alipay_public_key_string=open(settings.ALIPAY_SETTING.get('ALIPAY_PUBLIC_KEY_STRING')).read(),
            sign_type=settings.ALIPAY_SETTING.get('SIGN_TYPE'),  # RSA 或者 RSA2
            debug = settings.ALIPAY_SETTING.get('DEBUG'),  # 默认False
            # config = AliPayConfig(timeout=15)  # 可选, 请求超时时间
        )

        order_string = alipay.api_alipay_trade_page_pay(
            out_trade_no=order_number,
            total_amount=float(order_obj.real_price),
            subject=order_obj.order_title,
            return_url=settings.ALIPAY_SETTING.get('RETURN_URL'),
            notify_url=settings.ALIPAY_SETTING.get('NOTIFY_URL') # 可选, 不填则使用默认notify url
        )

        pay_page_url = settings.ALIPAY_SETTING.get('GATEWAY') + '?' + order_string

        return Response({'url': pay_page_url})


class PaymentCheckView(APIView):
    permission_classes = [IsAuthenticated, ]
    def get(self,request):
        data = request.query_params.dict()

        signature = data.pop("sign")
        alipay = AliPay(
            appid=settings.ALIPAY_SETTING.get('APP_ID'),
            app_notify_url=None,  # 默认回调url
            app_private_key_string=open(settings.ALIPAY_SETTING.get('APP_PRIVATE_KEY_STRING')).read(),
            # 支付宝的公钥，验证支付宝回传消息使用，不是你自己的公钥,
            alipay_public_key_string=open(settings.ALIPAY_SETTING.get('ALIPAY_PUBLIC_KEY_STRING')).read(),
            sign_type=settings.ALIPAY_SETTING.get('SIGN_TYPE'),  # RSA 或者 RSA2
            debug=settings.ALIPAY_SETTING.get('DEBUG'),  # 默认False
            # config = AliPayConfig(timeout=15)  # 可选, 请求超时时间
        )

        # verification
        success = alipay.verify(data, signature)
        # print('>>>>>',success)
        if success:
            #1 修改订单状态
            # try:

            res_data = self.res_data_return(request,data)

            # except:
            #     return Response({'error': '支付完成后，修改订单状态失败！'},status=500)
            return Response({'msg':'ok','res_data': res_data})

        else:
            return Response({'error': '支付宝响应数据校验失败'},status=400)


    # 支付宝异步结果通知处理
    def post(self,request):

        data = request.query_params.dict()
        signature = data.pop("sign")
        alipay = AliPay(
            appid=settings.ALIPAY_SETTING.get('APP_ID'),
            app_notify_url=None,  # 默认回调url
            app_private_key_string=open(settings.ALIPAY_SETTING.get('APP_PRIVATE_KEY_STRING')).read(),
            # 支付宝的公钥，验证支付宝回传消息使用，不是你自己的公钥,
            alipay_public_key_string=open(settings.ALIPAY_SETTING.get('ALIPAY_PUBLIC_KEY_STRING')).read(),
            sign_type=settings.ALIPAY_SETTING.get('SIGN_TYPE'),  # RSA 或者 RSA2
            debug=settings.ALIPAY_SETTING.get('DEBUG'),  # 默认False
            # config = AliPayConfig(timeout=15)  # 可选, 请求超时时间
        )

        # verification
        success = alipay.verify(data, signature)
        # print('>>>>>',success)
        if success and data["trade_status"] in ("TRADE_SUCCESS", "TRADE_FINISHED" ):
            self.res_data_return(request, data)
            return Response('success')

        else:
            return Response({'error': '支付宝响应数据校验失败'}, status=400)



    def res_data_return(self,request,data):
        current_time = datetime.datetime.now()
        order_number = data.get('out_trade_no')
        trade_no = data.get('trade_no')
        total_amount = data.get('total_amount')

        res_data = {
            'total_price': total_amount,
            'pay_time': current_time,
            'course_name': []

        }  # 响应信息
        with transaction.atomic():
            order_obj = Order.objects.get(order_number=order_number)
            order_obj.order_status = 1
            order_obj.save()

            # 2 优惠券修改状态为已经使用
            coupon_obj = UserCoupon.objects.get(id=order_obj.coupon)
            coupon_obj.is_use = True
            print(coupon_obj)
            coupon_obj.save()

            # 3 积分修改、积分记录添加
            user_obj = User.objects.get(id=request.user.id)
            user_obj.credit -= order_obj.credit
            user_obj.save()
            Credit.objects.create(user=user_obj, opera=2, number=order_obj.credit)
            # 5 购物车删除对应课程
            conn = get_redis_connection('cart')
            selected_course = conn.smembers(f'selected_{request.user.id}')  # 所有选中课程
            for course_id_bytes in selected_course:
                course_id = course_id_bytes.decode()
                expire_id = int(conn.hget(request.user.id, course_id).decode())
                # user_id:{course_id: expire_id}

                course_obj = Course.objects.get(id=course_id)
                res_data['course_name'].append(course_obj.name)

                if expire_id > 0:
                    expire = CourseExpire.objects.get(id=expire_id).expire_time  # 天数
                else:
                    expire = 100000
                conn.hdel(request.user.id, course_id)
                conn.srem(f'selected_{request.user.id}', course_id)

                # 4 保存支付宝的交易流水号（购买记录表）

                out_time = current_time + datetime.timedelta(days=expire)

                UserCourse.objects.create(
                    user_id=request.user.id,
                    course_id=course_id,
                    trade_no=trade_no,
                    buy_type=1,
                    pay_time=current_time,
                    out_time=out_time,
                )

        return res_data





